package com.blueocean_health.care.management.service;

import java.io.File;
import java.math.BigDecimal;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import com.blueocean_health.care.management.domain.base.*;
import com.blueocean_health.care.management.domain.dto.UpdateNurseDetailDto;
import com.blueocean_health.care.management.domain.dto.UpdateNurseDto;
import com.blueocean_health.care.management.domain.ordervo.*;
import com.blueocean_health.care.management.em.*;
import com.blueocean_health.care.management.mapper.*;
import com.blueocean_health.care.management.util.Arith;
import com.blueocean_health.care.management.util.JpushUtils;
import com.blueocean_health.care.management.util.MessageUtils;
import net.sf.ehcache.Cache;
import net.sf.ehcache.CacheManager;
import net.sf.ehcache.Element;
import net.sf.ehcache.store.StoreQuery;

import org.apache.ibatis.annotations.Delete;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.blueocean_health.care.management.common.base.em.TimeType;
import com.blueocean_health.care.management.common.base.id.IdUtils;
import com.blueocean_health.care.management.common.base.string.StringUtils;
import com.blueocean_health.care.management.common.base.time.TimeUtils;
import com.blueocean_health.care.management.exception.OrderException;
import com.blueocean_health.care.management.exception.OrderServiceException;
import com.blueocean_health.care.management.service.order_service_info.OrderServiceInfoService;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import javax.xml.transform.Source;

/**
 * @Author ChenPeng cp
 * @Date 2017/8/18 17:30
 */

@Service
public class OrderInfoServiceImpl implements OrderInfoService{

    @Autowired
    private OrderInfoMapper orderInfoMapper;

    @Autowired
    private OrderServiceInfoMapper orderServiceInfoMapper;

    @Autowired
    private OrderServiceInfoService orderServiceInfoService;

    @Autowired
    private IChareOrderService iChareOrderService;

    @Autowired
    private HospitalService hospitalService;

    @Autowired
    private OrderSendMsgMapper orderSendMsgMapper;

    @Autowired
    private OrderServiceNurseInfoMapper orderServiceNurseInfoMapper;

    @Autowired
    private SingleServiceMapper singleServiceMapper;
    @Autowired
    private UserService userService;

    @Autowired
    private TeamMapper teamMapper;

    @Autowired
    private OrderChargeInfoMapper orderChargeInfoMapper;


    @Override
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public SysResult insertOrderInfo(OrderInfoVo orderInfovo,String hospitalId,Integer userId,Long version,String orderType) throws OrderException {

        OrderInfo lastOrder = new OrderInfo();
        OrderInfo orderInfo = new OrderInfo();

        if (StringUtils.isEmpty(orderInfovo.getSex())){
            throw new OrderException("患者年龄不可以为空！");
        }

        //判断当前订单类型是新入还是续费 ，因为是一个接口，传的是一个参数
        String loginPhone = null;
        if (OrderTypeEnum._1.getKey().equals(orderType)){
            if (!StringUtils.isEmpty(orderInfovo.getSuperOrderId())){
                orderType = OrderTypeEnum._2.getKey();
                //续费的时候重置一下订单状态
                orderInfovo.setOrderStatus("");
                OrderInfo superOrder = orderInfoMapper.getLastOrderInfoById(orderInfovo.getSuperOrderId());
                loginPhone = superOrder.getLoginPhone();
            }
        }else {
            loginPhone = orderInfovo.getPhone();
        }

        //判断当前提交有无护工信息
        String OrderStatus = OrderStatusEnum._1.getKey();
        List<OrderDetail> detailList =  orderInfovo.getOrderDetail();
        long workerSize = detailList.stream().filter(orderDetail -> orderDetail.getWorkerInfo().getWorkers().size() > 0).count();

        //根据订单状态和明细&护工数量，校验当前保存是否通过
        if(orderInfovo.getAddFlag() == null){
            return SysResult.error("addFlag is null");
        }else if (orderInfovo.getAddFlag() == 1){
            if (detailList.size() < 1 || workerSize < 1){
                return SysResult.error("护工信息为空");
            }
        }else if (orderInfovo.getAddFlag() == 0){
            if (detailList.size() > 0 || workerSize > 0){
                return SysResult.error("暂存时护工信息需要为空");
            }
        } else if (orderInfovo.getAddFlag() != 1 && orderInfovo.getAddFlag() != 0) {
            return SysResult.error("addFlag is error");
        }

        //判断订单护工数量
        if (workerSize > 0){
            OrderStatus = OrderStatusEnum._2.getKey();
        }

        Date createTime = new Date();
        String refundOrderId = null;
        String serviceOrderId = null;
        String orderFrom = null;
        String accountFlag = null;
        Date accountTime = null;

        //新增or编辑标记
        boolean insertFlag = true;
        //判断订单是新增or编辑，进行 付款、订单状态、订单id、创建时间、医院id，userid 的初始化,
        if (StringUtils.isEmpty(orderInfovo.getOrderId())){
            insertFlag = true;
            String id =  IdUtils.getRandomIdByDateTime();
            orderInfo.setOrderId(id);
            orderInfovo.setOrderId(id);
            serviceOrderId = orderInfovo.getServiceOrderId();
            refundOrderId = orderInfovo.getRefundOrderId();
            orderFrom = OrderFromEnum.MANAGE.getKey();
            accountFlag = AccountFlagEnum._0.getKey();

            //新增退款单的时候，防止‘并发操作’导致两个退款都会提交
            if (OrderTypeEnum._3.getKey().equals(orderType)){
                //判断要退款的这个订单明细，是否已经被退款过
                OrderServiceInfo osi =  orderServiceInfoMapper.getOrderServiceInfoByServiceId(serviceOrderId);
                if (osi != null){
                    //如果这条明细已经被退款，抛出
                    if (ServiceRefundEnum._2.getKey().equals(osi.getServiceRefundFlag())){
                        return SysResult.error("页面内容已过期，请刷新后再操作");
                    }
                }
            }

        }else {
            insertFlag = false;
            OrderInfo orderInfoById = orderInfoMapper.getLastOrderInfoById(orderInfovo.getOrderId());
            if (orderInfoById == null){
                return SysResult.error("orderid is error");
            }

            /*//防止并发操作，一个停留在编辑页面，一个确认入账，入账后编辑页面提交，此时应该拦截
            if (AccountFlagEnum._1.getKey().equals(orderInfoById.getAccountFlag())){
                return SysResult.error("订单已入账，编辑失败");
            }*/
            //入账状态的订单，允许编辑，点击提交时，判断实际服务费之和与入账时的金额是否一致，若保持一致则提交成功；若金额不一致，则不允许保存
            if (AccountFlagEnum._1.getKey().equals(orderInfoById.getAccountFlag())){
                List<OrderServiceInfo> listByOrderIdAndVersion = orderServiceInfoMapper.getListByOrderIdAndVersion(orderInfoById.getOrderId(), orderInfoById.getVersion());
                double listTotal = listByOrderIdAndVersion.stream().mapToDouble(value -> value.getActualTotalPrice()).sum();
                double paramTotal = orderInfovo.getOrderDetail().stream().mapToDouble(value -> value.getChargeInfo().getActualTotalPrice().doubleValue()).sum();
                if(listTotal != paramTotal){
                    throw new OrderException("订单已入账，收据金额需与入账时金额一致");
                }
            }

            //编辑时，判断该订单有没有退费订单，有的话则不可以直接编辑，需要删除之后才可以编辑
            List<OrderInfo> refundOrderBySuperOrderId = orderInfoMapper.getRefundOrderBySuperOrderId(orderInfovo.getOrderId());
            if (refundOrderBySuperOrderId.size() > 0){
                return SysResult.error("请删除该订单的退款单后再编辑");
            }

            orderInfo.setOrderId(orderInfovo.getOrderId());
            lastOrder = this.orderInfoMapper.getLastOrderInfoById(orderInfovo.getOrderId());
            if (lastOrder != null){
                createTime = lastOrder.getCreateTime();
                hospitalId = lastOrder.getHospitalId();
                userId = lastOrder.getCreateUserid();
                loginPhone = lastOrder.getLoginPhone();
                serviceOrderId = lastOrder.getServiceOrderId();
                refundOrderId = lastOrder.getRefundOrderId();
                orderFrom = lastOrder.getOrderFrom();
                accountFlag = lastOrder.getAccountFlag();
                accountTime = lastOrder.getAccountTime();
            }
        }


        //获取订单付款状态
        String payStatus = null;
        ChareOrderVo chareOrderVo = new ChareOrderVo();
        if (orderInfovo.getMoneyStatus()){
            //根据收据信息录入结果为准
            ReceiptDetail receiptDetail = orderInfovo.getReceiptDetail();
            chareOrderVo.setHospitalId(hospitalId);
            chareOrderVo.setIsReceivables(orderInfovo.getMoneyStatus());
            chareOrderVo.setBillingTime(receiptDetail.getBillingTime());
            chareOrderVo.setOrderId(orderInfo.getOrderId());
            chareOrderVo.setOrderType(orderType);
            chareOrderVo.setPatientSign(receiptDetail.getPatientSign());
            chareOrderVo.setPatientSignDate(receiptDetail.getPatientSignDate());
            chareOrderVo.setReceiptNumber(receiptDetail.getReceiptNumber());
            chareOrderVo.setServiceId(orderInfovo.getServiceOrderId());
            chareOrderVo.setServiceOrderTime(orderInfovo.getServiceOrderTime());
            chareOrderVo.setTransType(receiptDetail.getTransType());
            chareOrderVo.setUserId(receiptDetail.getUserId());

            Boolean aBoolean =  iChareOrderService.receivablesnew(chareOrderVo);
            if (aBoolean){
                //退款单的资金状态为null
                if (OrderTypeEnum._3.getKey().equals(orderType)){
                    payStatus = null;
                }
                payStatus = PayStatusEnum._2.getKey();
            }else {
               return SysResult.error("收据编号重复录入，请复核后再填写");
            }
        }else {
            //未收款时，调用接口删除掉收据信息（如果有收据信息的话）
            chareOrderVo.setOrderId(orderInfo.getOrderId());
            chareOrderVo.setIsReceivables(false);
            Boolean aBoolean =  iChareOrderService.receivablesnew(chareOrderVo);
            if (aBoolean){
                payStatus = PayStatusEnum._1.getKey();
            }else {
                return SysResult.error("收据删除失败，请重试");
            }
        }
        //退款单的资金状态永远是已退款
        if (OrderTypeEnum._3.getKey().equals(orderType)){
            payStatus = PayStatusEnum._3.getKey();
        }

        //计算订单状态
        if (OrderTypeEnum._3.getKey().equals(orderType)){
            //如果是退款单
            OrderStatus = OrderStatusEnum._7.getKey();
        }else {
            //正常单和续费单根据订单明细时间得到订单实时状态
            List<Date> dateList = new ArrayList<>();
            Long now = System.currentTimeMillis();
            Long first = 0L;
            Long last = 0L;
            if (detailList.size() < 1){
                OrderStatus = OrderStatusEnum._1.getKey();
            }else {

                //校验订单明细必填项（用户端发起的订单在运营端会出现直接提交，但是必填项为空的问题）
                int errorSize = detailList.stream().filter(orderDetail -> {
                          return StringUtils.isEmpty(orderDetail.getEndTime()) ||
                            StringUtils.isEmpty(orderDetail.getWorkerInfo().getServiceType()) ||
                            StringUtils.isEmpty(orderDetail.getWorkerInfo().getWorkers().get(0).getWorkerId()) ||
                            StringUtils.isEmpty(orderDetail.getSickRoomInfo().getDepartment()) ||
                            StringUtils.isEmpty(orderDetail.getSickRoomInfo().getBedNumber()) ||
                            StringUtils.isEmpty(orderDetail.getSickRoomInfo().getFloor()) ||
                            StringUtils.isEmpty(orderDetail.getSickRoomInfo().getBuildingNumber());
                }).collect(Collectors.toList()).size();

                if (errorSize > 0){
                    return SysResult.error("请完善订单明细信息！");
                }

                int userOrder =  detailList.stream().filter(orderDetail -> {
                    long begin = orderDetail.getBeginTime().getTime();
                    long end = orderDetail.getEndTime().getTime();
                    return  begin == end;
                }).collect(Collectors.toList()).size();

                if (userOrder > 0){
                    return SysResult.error("订单明细开始时间不能与结束时间相同！");
                }


                //获取订单明细中最早时间和最晚时间
                detailList.forEach(orderDetail -> {
                    dateList.add(orderDetail.getBeginTime());
                    dateList.add(orderDetail.getEndTime());
                });
                Collections.sort(dateList);
                if (dateList.size() > 0){
                    first = dateList.get(0).getTime();
                    last = dateList.get(dateList.size()-1).getTime();
                }else {
                    return SysResult.error("订单明细缺少开始结束时间");
                }

                    //订单明细时间与当前时间比较
                    if (now < first) {
                        //当前时间小于开始时间  待服务
                        OrderStatus = OrderStatusEnum._2.getKey();
                    } else if (now >= first && last >= now) {
                        //当前时间大于开始时间小于结束时间 服务中
                        OrderStatus = OrderStatusEnum._3.getKey();
                    } else if (now > last){
                        //当前时间大于结束时间 已完成服务  若为退款中则不改动
                        if (OrderStatusEnum._4.getKey().equals(orderInfovo.getOrderStatus())){
                        }/*else if (OrderStatusEnum._5.getKey().equals(orderInfovo.getOrderStatus())){
                            //已经手动触发已完成的，也不动
                        }*/else if (OrderStatusEnum._7.getKey().equals(orderInfovo.getOrderStatus())){
                            //已经手动触发已退款的，也不动
                        }else{
                            OrderStatus = OrderStatusEnum._5.getKey();
                        }
                    } else {
                    }

            }
        }

        //校验退款单的明细时间段是否符合所退明细的时间段
        if (OrderTypeEnum._3.getKey().equals(orderType)){
            if (StringUtils.isEmpty(serviceOrderId)||StringUtils.isEmpty(refundOrderId)){
                return SysResult.error("参数缺少ServiceOrderId或者RefundOrderId");
            }else {
                OrderServiceInfo osi =  orderServiceInfoMapper.getOrderServiceInfoByServiceId(serviceOrderId);
                Date oldBegin =  osi.getBeginTime();
                Date oldEnd = osi.getEndTime();

                List<OrderDetail> orderDetail = orderInfovo.getOrderDetail();

                for (OrderDetail info:orderDetail) {
                    Date newEnd = info.getEndTime();
                    Date newBegin = info.getBeginTime();

                    if (newBegin.getTime() < oldBegin.getTime() || newEnd.getTime() > oldEnd.getTime()){
                        return SysResult.error("请选择正确的时间周期");
                    }
                }
            }
        }

        //退款中的订单 资金状态和订单状态不变
        if (!StringUtils.isEmpty(orderInfovo.getOrderStatus()) && OrderStatusEnum._8.getKey().equals(orderInfovo.getOrderStatus())){
                OrderStatus = OrderStatusEnum._8.getKey();
        }

        if (!StringUtils.isEmpty(orderInfovo.getPayStatus()) && PayStatusEnum._4.getKey().equals(orderInfovo.getPayStatus())){
            payStatus = PayStatusEnum._4.getKey();
        }

        orderInfo.setCreateTime(createTime);
        orderInfo.setHospitalId(hospitalId);
        orderInfo.setCreateUserid(userId);
        orderInfo.setPayStatus(payStatus);
        orderInfo.setOrderStatus(OrderStatus);

        orderInfo.setPatientName(orderInfovo.getPatientName());
        orderInfo.setSex(orderInfovo.getSex());
        orderInfo.setPhone(orderInfovo.getPhone());
        orderInfo.setLoginPhone(loginPhone);
        orderInfo.setContact(orderInfovo.getContact());
        orderInfo.setPatientRemark(orderInfovo.getPatientRemark());
        orderInfo.setPatientId(orderInfovo.getPatientId());
        orderInfo.setAdmissionTime(orderInfovo.getAdmissionTime());
        orderInfo.setAge(orderInfovo.getAge());
        orderInfo.setUpdateTime(new Date());
        orderInfo.setDeflag(OrderFlagEnum._0.getKey());
        orderInfo.setVersion(version);
        //订单拆分后新增字段
        orderInfo.setOrderType(orderType);
        orderInfo.setSuperOrderId(orderInfovo.getSuperOrderId());
        orderInfo.setRefundOrderId(refundOrderId);
        orderInfo.setServiceOrderId(serviceOrderId);
        orderInfo.setIntroducer(orderInfovo.getIntroducer());
        orderInfo.setProportions(orderInfovo.getProportions());
        orderInfo.setRenewFlag(OrderRenewEnum._0.getKey());
        //新增订单来源
        orderInfo.setOrderUpdateFlag(OrderUpdateFlagEnum._1.getKey());
        orderInfo.setOrderFrom(orderFrom);
        //入账状态
        orderInfo.setAccountFlag(accountFlag);
        orderInfo.setAccountTime(accountTime);

        int flag =  orderInfoMapper.insert(orderInfo);
        if (flag < 1){
            throw new OrderException("insert orderinfo failed");
        }
        orderServiceInfoService.updateOrderServiceInfo(orderInfovo,orderType,userId,hospitalId);
        //如果是退款单，把所退的订单的明细改为已退款状态
        if (OrderTypeEnum._3.getKey().equals(orderType)){
            orderServiceInfoMapper.updateServiceRefundFlagByServiceId(orderInfovo.getServiceOrderId(), ServiceRefundEnum._2.getKey());
        }

        //如果是续费的单子，把所续费订单标记为已续费
        if (OrderTypeEnum._2.getKey().equals(orderType)){
            //如果是编辑，不用管,只有新订单才改
            if(insertFlag){
                if (!StringUtils.isEmpty(orderInfovo.getRenewOrderId())){
                    orderInfoMapper.updateRenewFlagByOrderId(OrderRenewEnum._1.getKey(), orderInfovo.getRenewOrderId());
                }else {
                    throw new OrderException("续费订单缺少参数：RenewOrderId");
                }
            }
        }

//        throw new OrderException("insert orderinfo failed");
        return SysResult.ok().addData(orderInfo.getOrderId());
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public SysResult deleteOrRecoveryOrderInfo(String orderFlag, String orderId,String loginPhone) throws OrderException {

        if (StringUtils.isEmpty(orderFlag) || StringUtils.isEmpty(orderId) || StringUtils.isEmpty(loginPhone)){
            return SysResult.error("params is null");
        }
        OrderInfo lastOrderInfoById = orderInfoMapper.getLastOrderInfoById(orderId);
        if (StringUtils.isEmpty(lastOrderInfoById.getLoginPhone())){
            return SysResult.error("该订单暂无联系人手机号，暂不支持删除！");
        }
        if (!lastOrderInfoById.getLoginPhone().equals(loginPhone)){
            return SysResult.error("params is error");
        }
        if (!lastOrderInfoById.getOrderStatus().equals(OrderStatusEnum._1.getKey())){
            return SysResult.error("订单状态已变更，请刷新");
        }
        Boolean deflag = orderInfoMapper.updateOrderFlagByOrderId(orderFlag,orderId);
        if (deflag){
            orderServiceInfoService.deleteOrder(orderId);
            this.sendMsgFromUserToStaff(lastOrderInfoById);
            return SysResult.ok().addData(orderId);
        }
        else {
            return SysResult.error("db delete fail");
        }
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public SysResult updateOrderInfoStatus(String orderStatus, Integer id) throws OrderException {

        OrderInfo order = orderInfoMapper.selectByPrimaryKey(id);
        List<OrderInfo> lastOrderInfoList = orderInfoMapper.getLastOrderInfoByOrderId(order.getOrderId());

        long versionFlag = lastOrderInfoList.stream().filter(orderInfo -> {
           return orderInfo.getId().equals(id);
        }).count();

        if (versionFlag < 1) {
            throw new OrderException("页面内容已过期，请刷新后再操作");
        }
        
        //已入账订单不能进行编辑（情景：外勤端正在编辑 运营端点击入账  ）
  		String accountFlag = order.getAccountFlag();
  		//是否入账 0否 1是
  		if("1".equals(accountFlag)){
  			throw new OrderException("订单已入账，取消失败");
  		}
        if (StringUtils.isEmpty(orderStatus) || StringUtils.isEmpty(id)){
            return SysResult.error("params is null");
        }
        Boolean flag = orderInfoMapper.updateOrderStatusById(orderStatus,id);
        if (flag){
            if (OrderStatusEnum._6.getKey().equals(orderStatus)) {
                //原订单收款状态改为‘未收款’，删除相关收据
                //this.updateOrderPayStatusAndDelCharge(order.getOrderId());
                //删除所涉及的订单明细
                orderServiceInfoService.deleteOrder(order.getOrderId());
                //取消时退款单的处理
                this.deleteRefundOrderAndUpdateServiceRefundFlag(order.getOrderId());
                //入账状态的处理
                orderInfoMapper.updateOrderAccountFlagById(AccountFlagEnum._0.getKey(),id,TimeUtils.getTime(TimeType.yyyy_MM_dd));
                //取消订单时，短信通知用户
                this.sendMsgFromStaffToUser(order);
            }else {
                //恢复时，原订单收款状态改为‘未收款’，删除相关收据
                this.updateOrderPayStatusAndDelCharge(order.getOrderId());
            }

            return SysResult.ok().addData(id);
        }
        else {
            return SysResult.error("db update fail");
        }
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public SysResult updateOrderAccount(String accountFlag, Integer id,String accountTime) throws OrderException {

        OrderInfo order = orderInfoMapper.selectByPrimaryKey(id);
        List<OrderInfo> lastOrderInfoList = orderInfoMapper.getLastOrderInfoByOrderId(order.getOrderId());

        long versionFlag = lastOrderInfoList.stream().filter(orderInfo -> {
            return orderInfo.getId().equals(id);
        }).count();

        if (versionFlag < 1) {
            return SysResult.error("页面内容已过期，请刷新后再操作");
        }
        if (StringUtils.isEmpty(accountFlag) || StringUtils.isEmpty(id)){
            return SysResult.error("params is null");
        }
        if (accountFlag.equals(AccountFlagEnum._0.getKey())){
            String orderStatus = OrderStatusEnum._2.getKey()+OrderStatusEnum._3.getKey()+OrderStatusEnum._7.getKey()+OrderStatusEnum._5.getKey();
            boolean flag = orderStatus.contains(order.getOrderStatus());
            if (!flag){
                return SysResult.error("该订单状态不支持入账操作");
            }
            if(order.getPayStatus().equals(PayStatusEnum._1.getKey())){
                return SysResult.error("请先进行收款操作！");
            }
            if(AccountFlagEnum._1.getKey().equals(order.getAccountFlag())){
                return SysResult.error("该订单已进行过入账操作！");
            }
            accountFlag = "1";
        }else {
            if (!AccountFlagEnum._1.getKey().equals(order.getAccountFlag())){
                return SysResult.error("该订单还未进行入账操作");
            }
            accountFlag = "0";
        }

        boolean flag = orderInfoMapper.updateOrderAccountFlagById(accountFlag,id,accountTime);
        if (flag){
            return SysResult.ok().addData(id);
        }else {
            return SysResult.error("操作失败，请联系管理员");
        }

    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public SysResult updateOrderInfoStatusForSchedule(String orderStatus, Integer id) throws OrderException {

        OrderInfo order = orderInfoMapper.selectByPrimaryKey(id);

        if (orderStatus == null || id == null){
            return SysResult.error("params is null");
        }
        Boolean flag = orderInfoMapper.updateOrderStatusById(orderStatus,id);
        if (flag){
//            if (OrderStatusEnum._6.getKey().equals(orderStatus)) {
//            	//原订单收款状态改为‘未收款’，删除相关收据
//            	this.updateOrderPayStatusAndDelCharge(order.getOrderId());
//                //删除所涉及的订单明细
//                orderServiceInfoService.deleteOrder(order.getOrderId());
//                //取消时退款单的处理
//                this.deleteRefundOrderAndUpdateServiceRefundFlag(order.getOrderId());
//            }
            return SysResult.ok().addData(id);
        }
        else {
            return SysResult.error("db update fail");
        }
    }


    @Override
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public void deleteRefundOrderAndUpdateServiceRefundFlag(String orderId) throws OrderException{
        //先删除所有退款单的明细（后删除不行，条件就不通过了）
        List<OrderInfo> refundOrderList = orderInfoMapper.getRefundOrderBySuperOrderId(orderId);
        for (OrderInfo orderinfo : refundOrderList) {
            orderServiceInfoService.deleteOrder(orderinfo.getOrderId());
        }
        //把该订单涉及的退款单的收据信息删除
        List<OrderInfo> refundOrders = orderInfoMapper.getRefundOrderBySuperOrderId(orderId);
        List<String> orderIdList = new ArrayList<>();
        refundOrders.forEach(orderInfo -> orderIdList.add(orderInfo.getOrderId()));
        String[] orderIds = new String[orderIdList.size()];
        orderIdList.toArray(orderIds);
        iChareOrderService.delCharge(orderIds);
        //取消正常订单时，删除所关联的所有退款单，
        orderInfoMapper.deleteOrderByRefundOrderId(OrderFlagEnum._1.getKey(), orderId);
        //把明细的退款状态改为未退款
        orderServiceInfoMapper.updateServiceRefundFlagByOrderId(orderId, ServiceRefundEnum._1.getKey());
    }

    /**
    * @Description: 订单收款状态改为‘未收款’，删除相关收据
    * @param:入参
    * @return:出参
    * @throws:
    */
    @Override
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public void updateOrderPayStatusAndDelCharge(String orderId) throws OrderException{
        OrderInfo orderInfo = orderInfoMapper.getLastOrderInfoById(orderId);
        //收款状态改为未退款
        orderInfoMapper.updatePayStatusById(PayStatusEnum._1.getKey(),orderInfo.getId());
        //然后把该订单涉及收据信息删除
        String[] orderIds = {orderInfo.getOrderId()};
        iChareOrderService.delCharge(orderIds);
    }


    @Override
    public List<OrderInfo> getLastOrderInfoList() {
        return orderInfoMapper.getLastOrderInfoList();
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public SysResult insertUserOrder(UserOrderVo orderVo, Long version,String loginPhone) throws OrderException {

        String OrderStatus = OrderStatusEnum._1.getKey();
        String payStatus = PayStatusEnum._1.getKey();
        Date createTime = new Date();

        OrderInfo orderInfo = new OrderInfo();

        orderInfo.setCreateTime(createTime);
        orderInfo.setUpdateTime(createTime);
        orderInfo.setPayStatus(payStatus);
        orderInfo.setOrderStatus(OrderStatus);

        String orderId = IdUtils.getRandomIdByDateTime();
        orderInfo.setOrderId(orderId);
        orderInfo.setDeflag(OrderFlagEnum._0.getKey());
        orderInfo.setPatientName(orderVo.getPatientName()+"（网络）");
        orderInfo.setSex(orderVo.getSex());
        orderInfo.setContact(orderVo.getContact());
        orderInfo.setPhone(orderVo.getPhone());
        orderInfo.setHospitalId(orderVo.getHospital());
        orderInfo.setPatientRemark(orderVo.getPatientRemark());
        orderInfo.setLoginPhone(loginPhone);
        orderInfo.setDeflag(OrderFlagEnum._0.getKey());
        orderInfo.setVersion(version);

        //订单拆分后新加
        orderInfo.setOrderType(OrderTypeEnum._1.getKey());
        orderInfo.setRenewFlag(OrderRenewEnum._0.getKey());
        orderInfo.setPatientAddress(orderVo.getPatientAddress());
        //订单来源
        orderInfo.setOrderFrom(OrderFromEnum.USER.getKey());
        orderInfo.setOrderUpdateFlag(OrderUpdateFlagEnum._0.getKey());
        //入账状态
        orderInfo.setAccountFlag(AccountFlagEnum._0.getKey());

        int flag =  orderInfoMapper.insert(orderInfo);
        if (flag < 1){
            throw new OrderException("insert orderinfo failed");
        }
        orderServiceInfoService.updateOrderUserServiceInfo(orderVo, orderInfo.getOrderId());

        Team hospital = teamMapper.getTeamById(orderVo.getHospital());
        String hospitalPhone = hospital.getTeamStaffPhone();
        String resultPhone = hospitalService.getHospitalPhone(orderVo.getHospital());

        OrderInfo resultInfo = new OrderInfo();
        resultInfo.setPhone(resultPhone);
        resultInfo.setOrderId(orderInfo.getOrderId());

        if (isPhoneNumber(hospitalPhone)){
            boolean checkPhoneCache = OrderInfoServiceImpl.checkPhoneCacheIsNull(hospitalPhone);
            if (checkPhoneCache){
                String sex = null;
                if (SexEnum.MAN.getKey().equals(orderVo.getSex())){
                    sex = SexEnum.MAN.getVal();
                }else {
                    sex = SexEnum.WOMEN.getVal();
                }

                String creatTime = TimeUtils.getStringByDate(createTime,TimeType.yyyy_MM_dd_HH_mm_ss);
                //短信通知
                String msg = "【蓝海健康】新订单通知："+orderVo.getPatientName()+"-"+sex+"- "+orderVo.getPhone()+" ，已于"+creatTime+"预约"+orderVo.getServiceTypeName()+"服务，请尽快联系用户！";
                String s = MessageUtils.sendMessageNew(msg, hospitalPhone,1);

                OrderSendMsg orderSendMsg = new OrderSendMsg();
                orderSendMsg.setCreateTime(new Date());
                orderSendMsg.setMsg(msg);
                orderSendMsg.setOrderId(orderId);
                orderSendMsg.setResult(s);
                orderSendMsg.setPhone(hospitalPhone);
                orderSendMsgMapper.insert(orderSendMsg);
                //手机号放入缓存
                OrderInfoServiceImpl.putPhoneCache(hospitalPhone);
            }
        }
        //推送消息
        JpushToOutWorker(orderInfo);
        return SysResult.ok().addData(resultInfo);
    }
  private void JpushToOutWorker(OrderInfo orderInfo) {
	  String hospitalId = orderInfo.getHospitalId();
	  List<User> pushUserByHospitalId = userService.getPushUserByHospitalId(hospitalId);
	  String[] userIds = pushUserByHospitalId.stream().map(user -> user.getUserId()+"").toArray(String[]::new);
	  String content="您有一条用户发送的订单信息,患者："+orderInfo.getPatientName()+" 联系电话"+orderInfo.getPhone();
	  JpushUtils.testSendPush(userIds, content);	  
  }

  private static User testuser(User u){
	  u.setUserId(u.getUserId()+1);
	return u;
	  
  }
    @Override
    public Long getFirstOrderTime(String orderId, Long version) {
        OrderServiceInfo first = orderServiceInfoMapper.getFirstByOrderIdAndVersion(orderId, version);
        if (first == null){
            return null;
        }
        return first.getBeginTime().getTime();
    }

    @Override
    public Long getLastOrderTime(String orderId, Long version) {
        OrderServiceInfo last = orderServiceInfoMapper.getLastByOrderIdAndVersion(orderId, version);
        if (last == null){
            return null;
        }
        return last.getEndTime().getTime();
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public SysResult deleteOrderInfo(String orderFlag, String orderId) throws OrderServiceException {

        if (StringUtils.isEmpty(orderFlag) || StringUtils.isEmpty(orderId)){
            return SysResult.error("param is null");
        }
        final OrderInfo lastOrderInfoById = orderInfoMapper.getLastOrderInfoById(orderId);

        //校验非退款单子的状态是否符合删除操作（退款单可以直接删，其他单子必须是取消状态）
        if(!OrderTypeEnum._3.getKey().equals(lastOrderInfoById.getOrderType())){
            if (!OrderStatusEnum._6.getKey().equals(lastOrderInfoById.getOrderStatus())){
                return SysResult.error("order statue error");
            }
        }
        Boolean flag =  orderInfoMapper.updateOrderFlagByOrderId(orderFlag,orderId);
        if (!flag) {
            return SysResult.error("db delete fail");
        }
        orderServiceInfoService.deleteOrder(orderId);
        //删除退款单时把退款单所涉及的正常订单的订单明细改为未退款状态
        if (OrderTypeEnum._3.getKey().equals(lastOrderInfoById.getOrderType())){
            orderServiceInfoMapper.updateServiceRefundFlagByServiceId(lastOrderInfoById.getServiceOrderId(), ServiceRefundEnum._1.getKey());
        }
        //删除订单时，删除收据信息
        String[] orderIds = new String[]{lastOrderInfoById.getOrderId()};
        iChareOrderService.delCharge(orderIds);
        return SysResult.ok();
    }

    /**
     * 判断传入的字符串是否是一个手机号码
     *
     * @param strPhone
     * @return
     */
    public static boolean isPhoneNumber(String strPhone) {
        String str = "^((13[0-9])|(15[^4,\\D])|(18[0-9])|(17[0-9])|(14[0-9])|(16[0-9]))\\d{8}$";
        Pattern p = Pattern.compile(str);
        Matcher m = p.matcher(strPhone);
        return m.find();
    }


    public static void putPhoneCache(String Phone) {
        String property = System.getProperty("user.dir");
        String parentpath = new File(property).getParent();
        // 1. 创建缓存管理器
        CacheManager cacheManager = CacheManager.create(parentpath+"/core_properties/ehcache.xml");
        System.out.println("==========================");
        // 2. 获取缓存对象
        Cache cache = cacheManager.getCache("OrderMsgCache");

        // 3. 创建元素
        Element element = new Element(Phone, Phone);

        element.setTimeToIdle(12);
        element.setTimeToLive(12);
        // 4. 将元素添加到缓存
        cache.put(element);


    }

    public static boolean checkPhoneCacheIsNull(String Phone) {
        String property = System.getProperty("user.dir");
        String parentpath = new File(property).getParent();
        // 1. 创建缓存管理器
        CacheManager cacheManager = CacheManager.create(parentpath+"/core_properties/ehcache.xml");
        System.out.println("==========================");
        // 2. 获取缓存对象
        Cache cache = cacheManager.getCache("OrderMsgCache");
        boolean b = cache.get(Phone) == null;

        System.out.println(Phone +"----------" +b);
        //  获取缓存
        return b;

       /*  //  刷新缓存
        cache.flush();
        //  关闭缓存管理器
        cacheManager.shutdown();*/
    }

    @Override
    public void sendMsgFromUserToStaff(OrderInfo orderInfo){

        Team hospital = teamMapper.getTeamById(orderInfo.getHospitalId());
        String hospitalPhone = hospital.getTeamStaffPhone();

        if (isPhoneNumber(hospitalPhone)){
            boolean checkPhoneCache = OrderInfoServiceImpl.checkPhoneCacheIsNull(hospitalPhone);
            if (checkPhoneCache){
                String sex = null;
                if (SexEnum.MAN.getKey().equals(orderInfo.getSex())){
                    sex = SexEnum.MAN.getVal();
                }else {
                    sex = SexEnum.WOMEN.getVal();
                }

                OrderServiceNurseInfo orderServiceNurseInfo = orderServiceNurseInfoMapper.getMaxVersionByOrderId(orderInfo.getOrderId());

                String serviceTypeName = null;
                if (ServiceTypeEnum._1.getKey().equals(orderServiceNurseInfo.getServiceType())){
                    serviceTypeName = ServiceTypeEnum._1.getVal();
                }else if (ServiceTypeEnum._2.getKey().equals(orderServiceNurseInfo.getServiceType())){
                    serviceTypeName = ServiceTypeEnum._2.getVal();
                }else if (ServiceTypeEnum._3.getKey().equals(orderServiceNurseInfo.getServiceType())){
                    serviceTypeName = ServiceTypeEnum._3.getVal();
                }else {
                    serviceTypeName = ServiceTypeEnum._4.getVal();
                }
                //短信通知
                String msg = "【蓝海健康】取消订单通知：用户"+orderInfo.getPatientName()+"-"+sex+"- "+orderInfo.getPhone()+" 已取消"+serviceTypeName+"服务，如有疑问请与对方确认";
                String s = MessageUtils.sendMessageNew(msg, hospitalPhone,1);

                OrderSendMsg orderSendMsg = new OrderSendMsg();
                orderSendMsg.setCreateTime(new Date());
                orderSendMsg.setMsg(msg);
                orderSendMsg.setOrderId(orderInfo.getOrderId());
                orderSendMsg.setResult(s);
                orderSendMsg.setPhone(hospitalPhone);
                orderSendMsgMapper.insert(orderSendMsg);
                //手机号放入缓存
                OrderInfoServiceImpl.putPhoneCache(hospitalPhone);
            }
        }

    }

    @Override
    public void sendMsgFromStaffToUser(OrderInfo orderInfo){

        Team hospital = teamMapper.getTeamById(orderInfo.getHospitalId());
        String hospitalPhone = hospital.getTeamStaffPhone();
        String userPhone = orderInfo.getPhone();

        //只有来自用户端的订单才发送提示短信
        if (!OrderFromEnum.USER.getKey().equals(orderInfo.getOrderFrom())){
            return;
        }

        if (isPhoneNumber(userPhone)){
                OrderServiceNurseInfo orderServiceNurseInfo = orderServiceNurseInfoMapper.getMaxVersionByOrderId(orderInfo.getOrderId());

                String serviceTypeName = null;
                if (ServiceTypeEnum._1.getKey().equals(orderServiceNurseInfo.getServiceType())){
                    serviceTypeName = ServiceTypeEnum._1.getVal();
                }else if (ServiceTypeEnum._2.getKey().equals(orderServiceNurseInfo.getServiceType())){
                    serviceTypeName = ServiceTypeEnum._2.getVal();
                }else if (ServiceTypeEnum._3.getKey().equals(orderServiceNurseInfo.getServiceType())){
                    serviceTypeName = ServiceTypeEnum._3.getVal();
                }else {
                    serviceTypeName = ServiceTypeEnum._4.getVal();
                }

                //短信通知,不需要限制12S一次，所以isControl可以传null
                String msg = "【蓝海健康】取消订单通知：您好，您于"+TimeUtils.getStringByDate(orderInfo.getCreateTime(),TimeType.yyyy_MM_dd_HH_mm_ss)+"预约的"+serviceTypeName+"服务已被取消，如有疑问请联系 "+hospitalPhone+" ";
                String s = MessageUtils.sendMessageNew(msg, userPhone,null);

                OrderSendMsg orderSendMsg = new OrderSendMsg();
                orderSendMsg.setCreateTime(new Date());
                orderSendMsg.setMsg(msg);
                orderSendMsg.setOrderId(orderInfo.getOrderId());
                orderSendMsg.setResult(s);
                orderSendMsg.setPhone(hospitalPhone);
                orderSendMsgMapper.insert(orderSendMsg);
        }
    }

    @Override
    public SysResult getSingleService(Integer hid) {
        List<SingleService> singleServices = singleServiceMapper.queryAllSingleService(hid);
        List<SingleServiceVo> result = new ArrayList<>();
        singleServices.forEach(singleService -> {
            SingleServiceVo vo = new SingleServiceVo();
            vo.setSingleServiceId(singleService.getId()+"");
            vo.setSingleServiceName(singleService.getSingleServiceName());
            result.add(vo);
        });
        return SysResult.ok().addData(result);
    }


    /**
    * @Description: 更换护工接口，只是用来拆分数据，不进行任何数据库操作
    * @param:入参
    * @return:出参
    * @throws:
    */
    @Override
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public SysResult updateNurse(UpdateNurseDto dto) throws OrderServiceException {

        final OrderServiceInfo oldOrderService = orderServiceInfoMapper.getOrderServiceInfoByServiceId(dto.getOrderServiceId());
        Date oldStartTime = oldOrderService.getBeginTime();
        Date oldEndTime = oldOrderService.getEndTime();
        Date updateNurseTime = dto.getStartTime();
        //判断拆分时间是否合法
        if (updateNurseTime.getTime() <= oldStartTime.getTime() || updateNurseTime.getTime() >= oldEndTime.getTime()){
            //不能小于等于原开始时间，不能大于等于原结束时间
            throw new OrderServiceException("请选择正确的开始时间");
        }

        //距离原开始要大于1小时
        Calendar oldstr = Calendar.getInstance();
        oldstr.setTime(oldStartTime);
        oldstr.add(Calendar.HOUR, 1);
        if (updateNurseTime.getTime() < oldstr.getTime().getTime()){
            throw new OrderServiceException("请与原订单的开始时间至少相差1小时");
        }

        //距离原订单开始和结束时间都不能有分钟
        String oldServiceDay = null;
        String newServiceDay = null;
        String newInterval = null;
        String interval = getDatePoor(updateNurseTime,oldStartTime);
        String[] times = interval.split("-");
        String minutes = times[2];
        if(!"0".equals(minutes)){
            throw new OrderServiceException("与原订单开始时间的间隔不能出现分钟");
        }else {
            //计算出拆分之后的老明细和新明细的服务时间
            //老明细拆分之后的服务时间
            String oldDay = times[0];
            String oldHour = times[1];
            oldServiceDay = oldDay +"."+ oldHour;

            newInterval = getDatePoor(oldEndTime,updateNurseTime);
            String[] newTimes = newInterval.split("-");
            String newMinutes = newTimes[2];
            if(!"0".equals(newMinutes)){
                throw new OrderServiceException("与原订单结束时间的间隔不能出现分钟");
            }
            //新订单的服务时间
            String newDay = newTimes[0];
            String newHour = newTimes[1];
            newServiceDay = newDay +"."+newHour;

            //创建老明细数据
            OrderServiceInfo oldInfo = new OrderServiceInfo(oldOrderService);
            OrderServiceInfo newInfo = new OrderServiceInfo(oldOrderService);

            //判断是不是二对一的订单，二对一订单要用服务费总费是两倍
            Double serviceType = 1.0;
            if(oldOrderService.getServiceType().equals(ServiceTypeEnum._2.getKey())){
                serviceType = 2.0;
            }
            //重新计算的实际小时费用  = 原实际日工资/12or24
            //数据库中原明细的实际小时费用为“实际日费用/24(或者12)” ；
            Double hourPrice = 0.0;
            Double timeType = 0.0;
            if (OrderTimeTypeEnum._1.getKey().equals(oldOrderService.getOrderTypeFlag())){
                timeType = 24.0;
                //不可以在这进行四舍五入操作，因为会影响日费用计算的准确性
                hourPrice = Arith.div( oldOrderService.getActualDayPrice(),timeType);
            }else {
                timeType = 12.0;
                hourPrice = Arith.div( oldOrderService.getActualDayPrice(),timeType);
            }

            //重新计算的实际总费用
            Double dayTotalPrice = Arith.mul(oldOrderService.getActualDayPrice().doubleValue(),Double.parseDouble(oldDay));
            Double hourTotalPrice = Arith.mul(hourPrice,Double.parseDouble(oldHour));
            //算出总费用之后，根据是否是二对一来进行乘法计算
            Double actualTotalPrice = Arith.mul(Arith.add(dayTotalPrice,hourTotalPrice),serviceType);

            //重新计算的服务时间
            oldInfo.setDay(oldServiceDay);
            //重新计算的小时服务费用，保留两位小数，四舍五入
            BigDecimal b = new BigDecimal(hourPrice);
            b.setScale(2,BigDecimal.ROUND_HALF_UP);
            oldInfo.setOneHourPrice(b.doubleValue());
            //重新计算的实际总服务费
            oldInfo.setActualTotalPrice(actualTotalPrice);
            //老订单明细的结束时间改为拆分时间
            oldInfo.setEndTime(updateNurseTime);
            //因为要删除退款单，退款状态改为未退款
            oldInfo.setServiceRefundFlag(ServiceRefundEnum._1.getKey());
            oldInfo.setRefundServiceId(null);
            oldInfo.setServiceId(IdUtils.getRandomIdByDateTime());


            //计算新明细的实际总费用
            Double newActualTotalPrice = Arith.sub(oldOrderService.getActualTotalPrice(),actualTotalPrice);
            //计算新明细的实际小时费用
            //第二条的小时费用为“实际费用/(所有的小时数【将天转换为24小时或12小时】)”
            Double newHourTototla = Arith.add(Arith.mul(timeType,Double.parseDouble(newDay)),Double.parseDouble(newHour));
            //新明细的小时费用，要用新的总费用/总小时数/二对一or一对一
            Double newHourPrice = Arith.div(newActualTotalPrice,Arith.mul(newHourTototla,serviceType));
            Double newDayPrice = Arith.mul(newHourPrice,timeType);

            //重新计算的服务时间
            newInfo.setDay(newServiceDay);
            //重新计算的小时服务费用
            BigDecimal newb = new BigDecimal(newHourPrice);
            newb.setScale(2,BigDecimal.ROUND_HALF_UP);
            newInfo.setOneHourPrice(newb.doubleValue());
            //重新计算的日服务费
            BigDecimal newd = new BigDecimal(newDayPrice);
            newd.setScale(2,BigDecimal.ROUND_HALF_UP);
            newInfo.setOneDayPrice(newd.doubleValue());
            newInfo.setActualDayPrice(newd.doubleValue());
            //重新计算的实际总服务费
            newInfo.setActualTotalPrice(newActualTotalPrice);
            //订单开始时间为拆分时间
            newInfo.setBeginTime(updateNurseTime);
            //因为要删除退款单，退款状态改为未退款
            newInfo.setServiceRefundFlag(ServiceRefundEnum._1.getKey());
            newInfo.setRefundServiceId(null);
            newInfo.setServiceId(IdUtils.getRandomIdByDateTime());
            //附加费为0
            newInfo.setAdditionalPrice(0.0);
            newInfo.setHasAdditionalPrice(0);


            //删除原订单明细和所关联退款单
            this.deleteRefundOrderAndChargeByServiceId(oldOrderService.getServiceId());
            orderServiceInfoMapper.deleteOrderService(oldOrderService.getServiceId());

            //新增新订单明细
            int count = orderServiceInfoMapper.insert(oldInfo);
            if(count > 0){
                count = orderServiceInfoMapper.insert(newInfo);
                if (count <= 0){
                    throw new OrderServiceException("订单服务信息入库异常");
                }
            }else{
                throw new OrderServiceException("订单服务信息入库异常");
            }


            //通过serviceId拿到原护工明细集合，二对一时是集合
            List<OrderServiceNurseInfo> serviceNurseList = orderServiceNurseInfoMapper.getInfoByServiceId(oldOrderService.getServiceId());
            if (serviceNurseList.size() < 1 || serviceNurseList == null){
                throw new OrderServiceException("没有查到护工明细信息");
            }

            //计算老护工明细实际总护理费,按照乘法计算
            // 小时费用*小时数+天数*日费用，
            //老明细按照原订单的费用，新订单按照新费用

            //初始化入库数据
            OrderServiceNurseInfo dbInfoFir = serviceNurseList.get(0);
            OrderServiceNurseInfo oldServiceNurseFir = new OrderServiceNurseInfo(dbInfoFir);
            OrderServiceNurseInfo newServiceNurseFir = new OrderServiceNurseInfo(dbInfoFir);
            //计算拆分后，老户名明细的费用
            Double oldNurseDayPriceTotal = Arith.mul(oldServiceNurseFir.getOneDayPay(),Double.parseDouble(oldDay));
            Double oldNursHourPriceTotal = Arith.mul(oldServiceNurseFir.getOneHourPay(),Double.parseDouble(oldHour));
            Double oldNursePriceTotal = Arith.add(oldNurseDayPriceTotal,oldNursHourPriceTotal);

            oldServiceNurseFir.setTotalPay(oldNursePriceTotal);
            oldServiceNurseFir.setEndTime(updateNurseTime);
            oldServiceNurseFir.setServiceDay(oldServiceDay);
            oldServiceNurseFir.setFinallyDay(oldServiceDay);
            oldServiceNurseFir.setWorkerId(dbInfoFir.getWorkerId());
            //拆分后护工明细分别和服务明细关联
            oldServiceNurseFir.setServiceId(oldInfo.getServiceId());
            oldServiceNurseFir.setServNurseId(IdUtils.getRandomIdByDateTime());

            //计算新护工用户实际总护理费，新订单按照新费用
            UpdateNurseDetailDto paramInfoFir = dto.getList().get(0);

            if (StringUtils.isEmpty(paramInfoFir.getWorkerId())){
                throw new OrderServiceException("护工Id参数为空");
            }

            Double newNurseDayPriceTotal = Arith.mul(paramInfoFir.getDayPay().doubleValue(),Double.parseDouble(newDay));
            Double newNursHourPriceTotal = Arith.mul(paramInfoFir.getHourPay().doubleValue(),Double.parseDouble(newHour));
            Double newNursePriceTotal = Arith.add(newNurseDayPriceTotal,newNursHourPriceTotal);

            newServiceNurseFir.setTotalPay(newNursePriceTotal);
            newServiceNurseFir.setStartTime(updateNurseTime);
            newServiceNurseFir.setServiceDay(newServiceDay);
            newServiceNurseFir.setFinallyDay(newServiceDay);
            newServiceNurseFir.setWorkerId(paramInfoFir.getWorkerId());
            //拆分后护工明细分别和服务明细关联
            newServiceNurseFir.setServiceId(newInfo.getServiceId());
            newServiceNurseFir.setServNurseId(IdUtils.getRandomIdByDateTime());


            //入库第一条新老数据
            int insert = orderServiceNurseInfoMapper.insert(oldServiceNurseFir);
            if (insert > 0){
                insert = orderServiceNurseInfoMapper.insert(newServiceNurseFir);
                if (insert < 1){
                    throw new OrderServiceException("护工明细信息入库异常");
                }
            }else {
                throw new OrderServiceException("护工明细信息入库异常");
            }

            //二对一，两个护工明细都更换
            if (serviceNurseList.size() > 1){
                //老护工明细第二条
                OrderServiceNurseInfo dbInfoSen = serviceNurseList.get(1);
                OrderServiceNurseInfo oldServiceNurseSen = new OrderServiceNurseInfo(oldServiceNurseFir);

                oldNurseDayPriceTotal = Arith.mul(dbInfoSen.getOneDayPay(),Double.parseDouble(oldDay));
                oldNursHourPriceTotal = Arith.mul(dbInfoSen.getOneHourPay(),Double.parseDouble(oldHour));
                oldNursePriceTotal = Arith.add(oldNurseDayPriceTotal,oldNursHourPriceTotal);

                oldServiceNurseSen.setTotalPay(oldNursePriceTotal);
                oldServiceNurseSen.setWorkerId(dbInfoSen.getWorkerId());
                oldServiceNurseSen.setServNurseId(IdUtils.getRandomIdByDateTime());

                //新护工明细第二条
                UpdateNurseDetailDto paramInfoSen = dto.getList().get(1);
                OrderServiceNurseInfo newServiceNurseSen = new OrderServiceNurseInfo(newServiceNurseFir);

                if (StringUtils.isEmpty(paramInfoSen.getWorkerId())){
                    throw new OrderServiceException("护工Id参数为空");
                }

                newNurseDayPriceTotal = Arith.mul(paramInfoSen.getDayPay().doubleValue(),Double.parseDouble(newDay));
                newNursHourPriceTotal = Arith.mul(paramInfoSen.getHourPay().doubleValue(),Double.parseDouble(newHour));
                newNursePriceTotal = Arith.add(newNurseDayPriceTotal,newNursHourPriceTotal);

                newServiceNurseSen.setTotalPay(newNursePriceTotal);
                newServiceNurseSen.setWorkerId(paramInfoSen.getWorkerId());
                newServiceNurseSen.setServNurseId(IdUtils.getRandomIdByDateTime());

                insert = orderServiceNurseInfoMapper.insert(oldServiceNurseSen);
                if (insert > 0){
                    insert = orderServiceNurseInfoMapper.insert(newServiceNurseSen);
                }else {
                    throw new OrderServiceException("护工明细信息入库异常");
                }
            }

            if (insert > 0){
                //删除老数据
                insert = orderServiceNurseInfoMapper.deleteOrderServiceNurseInfoByServiceId(oldOrderService.getServiceId());
                if (insert < 1){
                    throw new OrderServiceException("护工明细信息入库异常");
                }
            }else {
                throw new OrderServiceException("护工明细信息入库异常");
            }
        }

        return SysResult.ok("更换成功");
    }

    /**
    * @Description: 通过所退serviceId删除退款单和收据信息
    * @param:入参
    * @return:出参
    * @throws:
    */
    @Override
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public void deleteRefundOrderAndChargeByServiceId(String serviceId) throws OrderServiceException {
        orderServiceInfoMapper.deleteRundOrderService(serviceId);
        orderServiceNurseInfoMapper.deleteRundOrderService(serviceId);
        orderChargeInfoMapper.deleteChargeByServiceId(serviceId);
    }


    private static String getDatePoor(Date endDate, Date nowDate) {
        long nd = 1000 * 24 * 60 * 60;
        long nh = 1000 * 60 * 60;
        long nm = 1000 * 60;
        // long ns = 1000;
        // 获得两个时间的毫秒时间差异
        long diff = endDate.getTime() - nowDate.getTime();
        // 计算差多少天
        long day = diff / nd;
        // 计算差多少小时
        long hour = diff % nd / nh;
        // 计算差多少分钟
        long min = diff % nd % nh / nm;

        // 计算差多少秒//输出结果
        // long sec = diff % nd % nh % nm / ns;
        return day + "-" + hour + "-" + min;
    }

    public static void main(String[] args) {


        OrderServiceInfo o = new OrderServiceInfo();
        o.setServiceId("111");
        o.setServiceRefundFlag("111");


        OrderServiceInfo b = new OrderServiceInfo(o);
        b.setServiceId("222");

        System.out.println(o.getServiceId());

        o.setServiceRefundFlag("333");


        System.out.println(b.getServiceRefundFlag());


        System.out.println( Arith.sub(2.2,1.9));



        }



}
